﻿<!doctype html>
<html lang="zh">
<head>
<meta charset="utf-8">
<title>在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像_技术宅大门</title>
<meta name="keywords" content="WebAssembly,Rust,eBPF,OCI 镜像">
<meta name="description" content="eBPF（extended Berkeley Packet Filter）是一种高性能的内核虚拟机，可以运行在内核空间中，以收集系统和网络信息。随着计算机技术的不断发展，eBPF 的功能日益强大，并且已经成为各种效率高效的在线诊断和跟踪系统，以及构建安全的网络、服务网格的重要组成部分。">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="static/css/base.css" rel="stylesheet">
<link href="static/css/m.css" rel="stylesheet">
<link href="static/css/swiper.min.css" rel="stylesheet">
<script src="static/js/jquery-3.6.0.min.js"></script>
<script src="static/js/comm.js"></script>
<!---代码高亮-->
<link href="static/css/shCoreDefault.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="static/js/shCore.js"></script>
<script type="text/javascript">
 SyntaxHighlighter.all();
</script>
</head>
<body>
<header>
  <div class="topbar"> <a href="index.html" class="logo">技术宅大门</a>
    <div class="search">
      <form action="/e/search/index.php" method="post" name="searchform" id="searchform">
        <input name="keyboard" id="keyboard" class="input_text" value="请输入关键字词" style="color: rgb(153, 153, 153);" onfocus="if(value=='请输入关键字词'){this.style.color='#000';value=''}" onblur="if(value==''){this.style.color='#999';value='请输入关键字词'}" type="text">
        <input name="show" value="title" type="hidden">
        <input name="tempid" value="1" type="hidden">
        <input name="tbname" value="news" type="hidden">
        <input name="Submit" class="input_submit" value="" type="submit">
      </form>
    </div>
  </div>
  <h2 id="mnavh"><span class="navicon"></span></h2>
</header>
<article>
  <nav>
    <div class="topnav">
      <ul id="starlist">
        <li><a href="index.html">最新文章</a></li>
        <li><a href="tuijian.html">推荐文章</a></li>
        <li><a href="hot.html">热门文章</a></li>
<li><a href="yunjisuan.html">云计算</a></li><li><a href="dashuju.html">大数据</a></li><li><a href="wulianwang.html">物联网</a></li><li><a href="qukuailian.html">区块链</a></li><li><a href="rengongzhineng.html">人工智能</a></li><li><a href="bianchengyuyan.html">编程语言</a></li><li><a href="yidongkaifa.html">移动开发</a></li> 
      </ul>
    </div>
    <em></em> </nav>
  <div class="box_l">
    <div class="weizhi"><a href="index.html">首页</a>&nbsp; / &nbsp;<a href="yunjisuan.html">云计算</a> / 在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像</div>
    <div class="con_tit">
      <h1>在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像</h1>
      <div class="con_info"><span class="con_tag">原创</span><span class="con_writer">于桐，郑昱笙</span><span class="con_class">分类：<a href="yunjisuan.html" target="_blank">云计算</a></span><span class="con_befrom">来源：DEVELOPERS</span> 
        <time>2023-03-23 12:13:45</time>
        <span class="con_link"><script src="static/js/-1_1_1.js"></script></span> </div>
    </div>
    <div class="content">
<p>eBPF（extended Berkeley Packet Filter）是一种高性能的内核虚拟机，可以运行在内核空间中，以收集系统和网络信息。随着计算机技术的不断发展，eBPF 的功能日益强大，并且已经成为各种效率高效的在线诊断和跟踪系统，以及构建安全的网络、服务网格的重要组成部分。</p>
<p>WebAssembly（Wasm）最初是以浏览器安全沙盒为目的开发的，发展到目前为止，WebAssembly 已经成为一个用于云原生软件组件的高性能、跨平台和多语言软件沙箱环境，Wasm 轻量级容器也非常适合作为下一代无服务器平台运行时，或在边缘计算等资源受限的场景高效执行。</p>
<p>现在，借助 Wasm-bpf 编译工具链和运行时，我们可以使用 Wasm 将 eBPF 程序编写为跨平台的模块，使用 C/C++ 和 Rust 编写程序。通过在 WebAssembly 中使用 eBPF 程序，我们不仅让 Wasm 应用获得 eBPF 的高性能、对系统接口的访问能力，还可以让 eBPF 程序享受到 Wasm 的沙箱、灵活性、跨平台性、和动态加载的能力，并且使用 Wasm 的 OCI 镜像来方便、快捷地分发和管理 eBPF 程序。例如，可以类似 docker 一样，从云端一行命令获取 Wasm 轻量级容器镜像，并运行任意 eBPF 程序。通过结合这两种技术，我们将会给 eBPF 和 Wasm 生态来一个全新的开发体验！</p>
<p>## 使用 Wasm-bpf 工具链在 Wasm 中编写、动态加载、分发运行 eBPF 程序</p>
<p>在前两篇短文中，我们已经介绍了 Wasm-bpf 的设计思路，以及如何使用 C/C++ 在 Wasm 中编写 eBPF 程序:</p>
<p>- Wasm-bpf: 架起 Webassembly 和 eBPF 内核可编程的桥梁</p>
<p>- 在 WebAssembly 中使用 C/C++ 和 libbpf 编写 eBPF 程序</p>
<p>基于 Wasm，我们可以使用多种语言构建 eBPF 应用，并以统一、轻量级的方式管理和发布。以我们构建的示例应用 bootstrap.wasm 为例，使用 C/C++ 构建的镜像大小最小仅为 ~90K，很容易通过网络分发，并可以在不到 100ms 的时间内在另一台机器上动态部署、加载和运行，并且保留轻量级容器的隔离特性。运行时不需要内核特定版本头文件、LLVM、clang 等依赖，也不需要做任何消耗资源的重量级的编译工作。对于 Rust 而言，编译产物会稍大一点，大约在 2M 左右。</p>
<p>本文将以 Rust 语言为例，讨论：</p>
<p>- 使用 Rust 编写 eBPF 程序并编译为 Wasm 模块</p>
<p>- 使用 OCI 镜像发布、部署、管理 eBPF 程序，获得类似 Docker 的体验</p>
<p>我们在仓库中提供了几个示例程序，分别对应于可观测、网络、安全等多种场景。</p>
<p>## 编写 eBPF 程序并编译为 Wasm 的大致流程</p>
<p>一般说来，在非 Wasm 沙箱的用户态空间，使用 libbpf-bootstrap 脚手架，可以快速、轻松地使用 C/C++构建 BPF 应用程序。编译、构建和运行 eBPF 程序（无论是采用什么语言），通常包含以下几个步骤：</p>
<p>- 编写内核态 eBPF 程序的代码，一般使用 C/C++ 或 Rust 语言</p>
<p>- 使用 clang 编译器或者相关工具链编译 eBPF 程序（要实现跨内核版本移植的话，需要包含 BTF 信息）。</p>
<p>- 在用户态的开发程序中，编写对应的加载、控制、挂载、数据处理逻辑；</p>
<p>- 在实际运行的阶段，从用户态将 eBPF 程序加载进入内核，并实际执行。</p>
<p>## 使用 Rust 编写 eBPF 程序并编译为 Wasm</p>
<p>Rust 可能是 WebAssembly 生态系统中支持最好的语言。Rust 不仅支持几个 WebAssembly 编译目标，而且 wasmtime、Spin、Wagi 和其他许多 WebAssembly 工具都是用 Rust 编写的。因此，我们也提供了 Rust 的开发示例：</p>
<p>- Wasm 和 WASI 的 Rust 生态系统非常棒</p>
<p>- 许多 Wasm 工具都是用 Rust 编写的，这意味着有大量的代码可以复用。</p>
<p>- Spin 通常在对其他语言的支持之前就有Rust的功能支持</p>
<p>- Wasmtime 是用 Rust编写的，通常在其他运行时之前就有最先进的功能。</p>
<p>- 可以在 WebAssembly 中使用许多现成的 Rust 库。</p>
<p>- 由于 Cargo 的灵活构建系统，一些 Crates 甚至有特殊的功能标志来启用Wasm的功能（例如Chrono）。</p>
<p>- 由于 Rust 的内存管理技术，与同类语言相比，Rust 的二进制大小很小。</p>
<p>我们同样提供了一个 Rust 的 eBPF SDK，可以使用 Rust 编写 eBPF 的用户态程序并编译为 Wasm。借助 aya-rs 提供的相关工具链支持，内核态的 eBPF 程序也可以用 Rust 进行编写，不过在这里，我们还是复用之前使用 C 语言编写的内核态程序。</p>
<p>首先，我们需要使用 rust 提供的 wasi 工具链，创建一个新的项目：</p>
<pre>
```sh
rustup target add wasm32-wasi
cargo new rust-helloworld
```</pre>
<p>之后，可以使用 `Makefile` 运行 make 完成整个编译流程，并生成 `bootstrap.bpf.o` eBPF 字节码文件。</p>
<p>### 使用 wit-bindgen 生成类型信息，用于内核态和 Wasm 模块之间通信</p>
<p>wit-bindgen 项目是一套着眼于 WebAssembly，并使用组件模型的语言的绑定生成器。绑定是用 *.wit 文件描述的，文件中描述了 Wasm 模块导入、导出的函数和接口。我们可以 wit-bindgen 它来生成多种语言的类型定义，以便在内核态的 eBPF 和用户态的 Wasm 模块之间传递数据。</p>
<p>我们首先需要在 `Cargo.toml` 配置文件中加入 `wasm-bpf-binding` 和 `wit-bindgen-guest-rust` 依赖：</p>
<pre>
```toml
wasm-bpf-binding = { path = &quot;wasm-bpf-binding&quot; }
```</pre>
<p>这个包提供了 wasm-bpf 由运行时提供给 Wasm 模块，用于加载和控制 eBPF 程序的函数的绑定。</p>
<pre>
- `wasm-bpf-binding` 在 wasm-bpf 仓库中有提供。
```toml
[dependencies]
wit-bindgen-guest-rust = { git = &quot;<a href="https://github.com/bytecodealliance/wit-bindgen" rel="nofollow" target="_blank">https://github.com/bytecodealliance/wit-bindgen</a>&quot;, version = &quot;0.3.0&quot; }
[patch.crates-io]
wit-component = {git = &quot;<a href="https://github.com/bytecodealliance/wasm-tools" rel="nofollow" target="_blank">https://github.com/bytecodealliance/wasm-tools</a>&quot;, version = &quot;0.5.0&quot;, rev = &quot;9640d187a73a516c42b532cf2a10ba5403df5946&quot;}
wit-parser = {git = &quot;<a href="https://github.com/bytecodealliance/wasm-tools" rel="nofollow" target="_blank">https://github.com/bytecodealliance/wasm-tools</a>&quot;, version = &quot;0.5.0&quot;, rev = &quot;9640d187a73a516c42b532cf2a10ba5403df5946&quot;}
```</pre>
<p>这个包支持用 wit 文件为 rust 客户程序生成绑定。使用这个包的情况下，我们不需要再手动运行 wit-bindgen。</p>
<p>接下来，我们使用 `btf2wit` 工具，从 BTF 信息生成 wit 文件。可以使用 `cargo install btf2wit` 安装我们提供的 btf2wit 工具，并编译生成 wit 信息：</p>
<pre>
```console
cd btf
clang -target bpf -g event-def.c -c -o event.def.o
btf2wit event.def.o -o event-def.wit
cp *.wit ../wit/
```</pre>
<p>- 其中 `event-def.c` 是包含了我们需要的结构体信息的的 C 程序文件。只有在导出符号中用到的结构体才会被记录在 BTF 中。</p>
<p>对于 C 结构体生成的 wit 信息，大致如下：</p>
<pre>
```wit
default world host {
    record event {
         pid: s32,
        ppid: s32,
        exit-code: u32,
        --pad0: list&lt;s8&gt;,
       duration-ns: u64,
        comm: list&lt;s8&gt;,
        filename: list&lt;s8&gt;,
        exit-event: s8,
    }
}
```</pre>
<p>`wit-bindgen-guest-rust` 会为 wit 文件夹中的所有类型信息，自动生成 rust 的类型，例如：</p>
<p>```rust</p>
<p>#[repr(C, packed)]</p>
<p>#[derive(Debug, Copy, Clone)]</p>
<p>struct Event {</p>
<p>&nbsp; &nbsp; pid: i32,</p>
<p>&nbsp; &nbsp; ppid: i32,</p>
<p>&nbsp; &nbsp; exit_code: u32,</p>
<p>&nbsp; &nbsp; __pad0: [u8; 4],</p>
<p>&nbsp; &nbsp; duration_ns: u64,</p>
<p>&nbsp; &nbsp; comm: [u8; 16],</p>
<p>&nbsp; &nbsp; filename: [u8; 127],</p>
<p>&nbsp; &nbsp; exit_event: u8,</p>
<p>}</p>
<p>```</p>
<p>### 编写用户态加载和处理代码</p>
<p>为了在 WASI 上运行，需要为 main.rs 添加 `#![no_main]` 属性，并且 main 函数需要采用类似如下的形态：</p>
<p>```rust</p>
<p>#[export_name = &quot;__main_argc_argv&quot;]</p>
<p>fn main(_env_json: u32, _str_len: i32) -&gt; i32 {</p>
<p>&nbsp; &nbsp; return 0;</p>
<p>}</p>
<p>```</p>
<p>用户态加载和挂载代码，和 C/C++ 中类似：</p>
<p>```rust</p>
<p>&nbsp; &nbsp; let obj_ptr =</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; binding::wasm_load_bpf_object(bpf_object.as_ptr() as u32, bpf_object.len() as i32);</p>
<p>&nbsp; &nbsp; if obj_ptr == 0 {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; println!(&quot;Failed to load bpf object&quot;);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; return 1;</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; let attach_result = binding::wasm_attach_bpf_program(</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; obj_ptr,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &quot;handle_exec\0&quot;.as_ptr() as u32,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &quot;\0&quot;.as_ptr() as u32,</p>
<p>&nbsp; &nbsp; );</p>
<p>&nbsp; &nbsp; ...</p>
<p>```</p>
<p>polling ring buffer：</p>
<p>```rust</p>
<p>&nbsp; &nbsp; let map_fd = binding::wasm_bpf_map_fd_by_name(obj_ptr, &quot;rb\0&quot;.as_ptr() as u32);</p>
<p>&nbsp; &nbsp; if map_fd &lt; 0 {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; println!(&quot;Failed to get map fd: {}&quot;, map_fd);</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; return 1;</p>
<p>&nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; // binding::wasm</p>
<p>&nbsp; &nbsp; let buffer = [0u8; 256];</p>
<p>&nbsp; &nbsp; loop {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; // polling the buffer</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; binding::wasm_bpf_buffer_poll(</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; obj_ptr,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; map_fd,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; handle_event as i32,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer.as_ptr() as u32,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buffer.len() as i32,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 100,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; );</p>
<p>&nbsp; &nbsp; }</p>
<p>```</p>
<p>使用 handler 接收返回值：</p>
<p>```rust</p>
<p>extern &quot;C&quot; fn handle_event(_ctx: u32, data: u32, _data_sz: u32) {</p>
<p>&nbsp; &nbsp; let event_slice = unsafe { slice::from_raw_parts(data as *const Event, 1) };</p>
<p>&nbsp; &nbsp; let event = &amp;event_slice[0];</p>
<p>&nbsp; &nbsp; let pid = event.pid;</p>
<p>&nbsp; &nbsp; let ppid = event.ppid;</p>
<p>&nbsp; &nbsp; let exit_code = event.exit_code;</p>
<p>&nbsp; &nbsp; if event.exit_event == 1 {</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; print!(</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;{:&lt;8} {:&lt;5} {:&lt;16} {:&lt;7} {:&lt;7} [{}]&quot;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;TIME&quot;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;EXIT&quot;,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; unsafe { CStr::from_ptr(event.comm.as_ptr() as *const i8) }</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .to_str()</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .unwrap(),</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pid,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ppid,</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; exit_code</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; );</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; ...</p>
<p>}</p>
<p>```</p>
<p>接下来即可使用 cargo 编译运行：</p>
<p>```console</p>
<p>$ cargo build --target wasi32-wasm</p>
<p>$ sudo wasm-bpf ./target/wasm32-wasi/debug/rust-helloworld.wasm</p>
<p>TIME &nbsp; &nbsp; EXEC &nbsp;sh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180245 &nbsp;33666 &nbsp; /bin/sh</p>
<p>TIME &nbsp; &nbsp; EXEC &nbsp;which &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;180246 &nbsp;180245 &nbsp;/usr/bin/which</p>
<p>TIME &nbsp; &nbsp; EXIT &nbsp;which &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;180246 &nbsp;180245 &nbsp;[0] (1ms)</p>
<p>TIME &nbsp; &nbsp; EXIT &nbsp;sh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180245 &nbsp;33666 &nbsp; [0] (3ms)</p>
<p>TIME &nbsp; &nbsp; EXEC &nbsp;sh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180247 &nbsp;33666 &nbsp; /bin/sh</p>
<p>TIME &nbsp; &nbsp; EXEC &nbsp;ps &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180248 &nbsp;180247 &nbsp;/usr/bin/ps</p>
<p>TIME &nbsp; &nbsp; EXIT &nbsp;ps &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180248 &nbsp;180247 &nbsp;[0] (23ms)</p>
<p>TIME &nbsp; &nbsp; EXIT &nbsp;sh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180247 &nbsp;33666 &nbsp; [0] (25ms)</p>
<p>TIME &nbsp; &nbsp; EXEC &nbsp;sh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 180249 &nbsp;33666 &nbsp; /bin/sh</p>
<p>TIME &nbsp; &nbsp; EXEC &nbsp;cpuUsage.sh &nbsp; &nbsp; &nbsp;180250 &nbsp;180249 &nbsp;/root/.vscode-server-insiders/bin/a7d49b0f35f50e460835a55d20a00a735d1665a3/out/vs/base/node/cpuUsage.sh</p>
<p>```</p>
<p>## 使用 OCI 镜像发布和管理 eBPF 程序</p>
<p>开放容器协议 (OCI) 是一个轻量级，开放的治理结构，为容器技术定义了规范和标准。在 Linux 基金会的支持下成立，由各大软件企业构成，致力于围绕容器格式和运行时创建开放的行业标准。其中包括了使用 Container Registries 进行工作的 API，正式名称为 OCI 分发规范 (又名&ldquo;distribution-spec&rdquo;)。</p>
<p>Docker 也宣布推出与 WebAssembly 集成 (Docker+Wasm) 的首个技术预览版，并表示公司已加入字节码联盟 (Bytecode Alliance)，成为投票成员。Docker+Wasm 让开发者能够更容易地快速构建面向 Wasm 运行时的应用程序。</p>
<p>借助于 Wasm 的相关生态，可以非常方便地发布、下载和管理 eBPF 程序，例如，使用 `wasm-to-oci` 工具，可以将 Wasm 程序打包为 OCI 镜像，获取类似 docker 的体验：</p>
<p>```console</p>
<p>wasm-to-oci push testdata/hello.wasm &lt;oci-registry&gt;.azurecr.io/wasm-to-oci:v1</p>
<p>wasm-to-oci pull &lt;oci-registry&gt;.azurecr.io/wasm-to-oci:v1 --out test.wasm</p>
<p>```</p>
<p>我们也将其集成到了 eunomia-bpf 的 ecli 工具中，可以一行命令从云端的 Github Packages 中下载并运行 eBPF 程序，或通过 Github Packages 发布：</p>
<p>```bash</p>
<p># push to Github Packages</p>
<p>ecli push&nbsp;<a href="https://ghcr.io/eunomia-bpf/sigsnoop" rel="nofollow" target="_blank">https://ghcr.io/eunomia-bpf/sigsnoop</a>:latest</p>
<p># pull from Github Packages</p>
<p>ecli pull&nbsp;<a href="https://ghcr.io/eunomia-bpf/sigsnoop" rel="nofollow" target="_blank">https://ghcr.io/eunomia-bpf/sigsnoop</a>:latest</p>
<p># run eBPF program</p>
<p>ecli run&nbsp;<a href="https://ghcr.io/eunomia-bpf/sigsnoop" rel="nofollow" target="_blank">https://ghcr.io/eunomia-bpf/sigsnoop</a>:latest</p>
<p>```</p>
<p>我们已经在 LMP 项目的 eBPF Hub 中，有一些创建符合 OCI 标准的 Wasm-eBPF 应用程序，并利用 ORAS 简化扩展 eBPF 应用开发，分发、加载、运行能力的尝试[11]，以及基于 Wasm 同时使用多种不同语言开发 eBPF 的用户态数据处理插件的实践。基于最新的 Wasm-bpf 框架，有更多的探索性工作可以继续展开，我们希望尝试构建一个完整的针对 eBPF 和 Wasm 程序的包管理系统，以及更多的可以探索的应用场景。</p>
<p>## 总结</p>
<p>本文以 Rust 语言为例，讨论了使用 Rust 编写 eBPF 程序并编译为 Wasm 模块以及使用 OCI 镜像发布、部署、管理 eBPF 程序，获得类似 Docker 的体验。更完整的代码，请参考我们的 Github 仓库：&lt;<a href="https://github.com/eunomia-bpf/wasm-bpf" rel="nofollow" target="_blank">https://github.com/eunomia-bpf/wasm-bpf</a>&gt;.</p>
<p>接下来，我们会继续完善在 Wasm 中使用多种语言开发和运行 eBPF 程序的体验，提供更完善的示例和用户态开发库/工具链，以及更具体的应用场景。</p>
<p>## 参考资料</p>
<blockquote>
<p>- wasm-bpf Github 开源地址：&lt;<a href="https://github.com/eunomia-bpf/wasm-bpf" rel="nofollow" target="_blank">https://github.com/eunomia-bpf/wasm-bpf</a>&gt;</p>
<p>- WASI-eBPF: &lt;<a href="https://github.com/WebAssembly/WASI/issues/513" rel="nofollow" target="_blank">https://github.com/WebAssembly/WASI/issues/513</a>&gt;</p>
<p>- eunomia-bpf 项目：&lt;<a href="https://github.com/eunomia-bpf/eunomia-bpf" rel="nofollow" target="_blank">https://github.com/eunomia-bpf/eunomia-bpf</a>&gt;</p>
<p>- eunomia-bpf 项目龙蜥 Gitee 镜像：&lt;<a href="https://gitee.com/anolis/eunomia" rel="nofollow" target="_blank">https://gitee.com/anolis/eunomia</a>&gt;</p>
<p>- LMP eBPF-Hub: &lt;<a href="https://github.com/linuxkerneltravel/lmp" rel="nofollow" target="_blank">https://github.com/linuxkerneltravel/lmp</a>&gt;</p>
<p>- wasm-to-oci: &lt;<a href="https://github.com/engineerd/wasm-to-oci" rel="nofollow" target="_blank">https://github.com/engineerd/wasm-to-oci</a>&gt;</p>
<p>- btf2wit: &lt;<a href="https://github.com/eunomia-bpf/btf2wit" rel="nofollow" target="_blank">https://github.com/eunomia-bpf/btf2wit</a>&gt;</p></blockquote>    </div>
<script>
var paras = document.getElementsByTagName("pre");
for ( var i=0;i<paras.length;i++ ) {
    paras[i].setAttribute("class","brush:php;toolbar:false");     
}
</script>
    <div class="con_tags"><a href="-WebAssembly.html" target="_blank">WebAssembly</a> &nbsp; <a href="-Rust.html" target="_blank">Rust</a> &nbsp; <a href="-eBPF.html" target="_blank">eBPF</a> &nbsp; <a href="-OCI镜像.html" target="_blank">OCI 镜像</a></div>
    <div class="info-pre-next">
      <p>上一篇：<a href='yunjisuan.html'>返回列表</a></p>
      <p>下一篇：<a href='2.html'>配置应用签名信息</a></p>
    </div>
    <div class="hot_news other_news">
      <div class="side_title">
        <h3>相关文章</h3>
      </div>
      <ul>
<li><a href="2.html" title="配置应用签名信息">配置应用签名信息</a></li><li><a href="" title="在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像">在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像</a></li>      </ul>
    </div>
    <div class="blog_list">
      <div class="side_title">
        <h3>猜你喜欢</h3>
      </div>
      <ul>


<li><a href="3.html" class="blog_more">
          <h2>爬虫时IP代理不能用？考虑以下几点原因</h2>
          <div class="ps"><span class="ps_tj">推荐</span></div>
           <i><img src="static/picture/banner1.jpg" alt="爬虫时IP代理不能用？考虑以下几点原因"></i>
          <p>代理服务商提供的IP大多数资源都是及时的。如果客户不能使用代理，IP正常访问网络，可以先检查代理IP是否有效IP生命周期不固定，受到影响IP类型，IP受质量等因素影响，有的生存时间短，几秒钟或几分钟，有的时间长，十几个小时或几天。通过测试或直接更改其他代理IP判断其不能使用的原因是比较直接快捷的方法。</p>
          </a>
          <div class="info"> <span class="info_class"><a href="dashuju.html" target="_blank">大数据</a></span><span class="info_time">2023-03-23</span><span class="info_view">19</span></div>
</li>


<li><a href="6.html" class="blog_more">
          <h2>智能合约开发实战——元交易（Metatransaction），元交易合约的实现</h2>
          <div class="ps"><span class="ps_tj">推荐</span></div>
          
          <p>引言前一篇文章（可以看我主页哦）中提到，普通的 ETH 交易并不能够做到让用户无需 gas 费，需要交易中嵌套一个交易，即元交易，来实现免 gas 费。本文将分析开源库 OpenZeppelin/openzeppelin-contracts 中的元交易合约的实现，让你能够快速入门元交易实现细节，从而能够自己对后续更多的相关技术</p>
          </a>
          <div class="info"> <span class="info_class"><a href="qukuailian.html" target="_blank">区块链</a></span><span class="info_time">2023-03-23</span><span class="info_view">2</span></div>
</li>


<li><a href="2.html" class="blog_more">
          <h2>配置应用签名信息</h2>
          <div class="ps"><span class="ps_tj">推荐</span><span class="ps_yc">原创</span></div>
          
          <p>准备签名文件									文件名称						作用												0密钥文件（.p12文件）						用于打包项目时进行签名、获取签名证书指纹。										证书请求文件（.csr）						用于向华为申请调试证书、发布证书。												表1 需准备的签名文件清单			搭建完开发环境后，您需要使用DevEco Studio</p>
          </a>
          <div class="info"> <span class="info_class"><a href="yunjisuan.html" target="_blank">云计算</a></span><span class="info_time">2023-03-23</span><span class="info_view">9</span></div>
</li>


<li><a href="5.html" class="blog_more">
          <h2>边缘计算：盘点100个知识点</h2>
          <div class="ps"><span class="ps_tj">推荐</span></div>
          
          <p>第三代、第四代和第五代蜂窝技术。简单来说，3G 代表智能手机及其移动网络浏览器的引入；4G 是当前一代的蜂窝技术，为移动设备提供真正的宽带互联网接入；5G 蜂窝技术将为蜂窝系统提供巨大的带宽并减少延迟，支持从智能手机到自动驾驶汽车和大规模物联网的一系列设备。边缘计算被认为是 5G 的关键组成部分。</p>
          </a>
          <div class="info"> <span class="info_class"><a href="rengongzhineng.html" target="_blank">人工智能</a></span><span class="info_time">2023-03-23</span><span class="info_view">16</span></div>
</li>


<li><a href="4.html" class="blog_more">
          <h2>大型物联网平台如何来保障亿级设备安全连接上云？</h2>
          <div class="ps"><span class="ps_tj">推荐</span><span class="ps_yc">原创</span></div>
           <i><img src="static/picture/smallbe1f74a105679c41ce1a12ed9e8cee691679550511.png" alt="大型物联网平台如何来保障亿级设备安全连接上云？"></i>
          <p>摘要：华为云IoT设备接入云服务（后续章节简称为“IoTDA”）提供海量设备的接入和管理能力，可以将IoT设备联接到华为云，支撑设备数据采集上云和云端下发命令给设备进行远程控制，配合华为云其他产品，帮助快速构筑物联网解决方案。</p>
          </a>
          <div class="info"> <span class="info_class"><a href="wulianwang.html" target="_blank">物联网</a></span><span class="info_time">2023-03-23</span><span class="info_view">6</span></div>
</li>


<li><a href="7.html" class="blog_more">
          <h2>【Kafka系列教程】088：Kafka Streams之概念——状态</h2>
          <div class="ps"></div>
          
          <p>某些流处理应用程序不需要状态，这意味着消息的处理独立于所有其他消息的处理。然而，能够维护状态为复杂的流处理应用程序打开了许多可能性：您可以加入输入流，或分组和聚合数据记录。许多这样的有状态运算符是由Kafka Streams DSL.Kafka Streams提供了所谓的状态存储，流处理应用程序可以</p>
          </a>
          <div class="info"> <span class="info_class"><a href="dashuju.html" target="_blank">大数据</a></span><span class="info_time">2023-03-23</span><span class="info_view">5</span></div>
</li>
      </ul>
    </div>
  </div>
  <div class="box_r">
    <div class="hot_news">
      <div class="side_title">
        <h3>最近文章</h3>
      </div>
      <ul>
        <li><a href="2.html" target="_blank">
          <p>配置应用签名信息</p>
          </a><span>9</span></li>
        <li><a href="" target="_blank">
          <p>在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像</p>
          </a><span>26</span></li>
      </ul>
    </div>
    <div class="tags">
      <div class="side_title"><a href="tags.html">更多</a>
        <h3>热门标签</h3>
      </div>
      <ul>
<li><a href="-WebAssembly.html">WebAssembly</a></li><li><a href="-Rust.html">Rust</a></li><li><a href="-eBPF.html">eBPF</a></li><li><a href="-OCI镜像.html">OCI镜像</a></li><li><a href="-爬虫.html">爬虫</a></li><li><a href="-IP代理.html">IP代理</a></li><li><a href="-元交易.html">元交易</a></li><li><a href="-Leetcode.html">Leetcode</a></li>      </ul>
    </div>
    <div class="tj_news">
      <div class="side_title">
        <h3>站长推荐</h3>
      </div>
      <ul>
        <li><a href="2.html" target="_blank">
          <p>配置应用签名信息</p>
          </a></li>
        <li><a href="" target="_blank">
          <p>在 WebAssembly 中使用 Rust 编写 eBPF 程序并发布 OCI 镜像</p>
          </a></li>
      </ul>
    </div>
  </div>
</article>
<footer>
  <div class="box">
    <div class="copyright">
      <p>Copyright © 技术宅大门 
      <p>备案号 <a href="https://beian.miit.gov.cn/" target="_blank">粤ICP备2024236460号-2</a> ｜ <img src="static/picture/ga.png" alt="">｜<a href="sitemap.xml" target="_blank">网站地图</a></p>
    </div>
  </div>
</footer>
<div class="side_nav">
  <ul>
    <li><a href="about.html" title="关于博主"><i class="icon_ab"><img src="static/picture/ft_about.png" alt=""></i> </a></li>
    <li><a href="gbook.html" title="在线留言"><i class="icon_qq"><img src="static/picture/ft_qq.png" alt=""></i> </a></li>
    <li><a title="个人微信"><i class="icon_wx"><img src="static/picture/ft_ewm.png" alt=""></i><span><img src="static/picture/wx.png" alt="微信"></span> </a></li>
    <li><a href="#" class="icon-top" title="返回顶部"><i class="icon_fh"><img src="static/picture/ft_top.png" alt=""></i> </a></li>
  </ul>
</div><script src="static/js/js.js"></script></body>
</html>